package com.ruoyi.gd.wjglfl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.gd.fj.domain.vo.ZFujianVo;
import com.ruoyi.gd.ywdwgd.domain.ZYwdwgd;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.gd.wjglfl.domain.bo.ZWjglFlBo;
import com.ruoyi.gd.wjglfl.domain.vo.ZWjglFlVo;
import com.ruoyi.gd.wjglfl.domain.ZWjglFl;
import com.ruoyi.gd.wjglfl.mapper.ZWjglFlMapper;
import com.ruoyi.gd.wjglfl.service.IZWjglFlService;

import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件管理分类Service业务层处理
 *
 * @author ruoyi
 * @date 2024-10-27
 */
@RequiredArgsConstructor
@Service
public class ZWjglFlServiceImpl implements IZWjglFlService {

    @Resource
    private ZWjglFlMapper baseMapper;

    @Value("${upload.wjgl}")
    private String uploadPath;

    /**
     * 查询文件管理分类
     */
    @Override
    public ZWjglFlVo queryById(String id){
        return baseMapper.selectVoById(id);
    }


    /**
     * 查询文件管理分类列表
     */
    @Override
    public List<Tree<String>> queryList(ZWjglFlBo bo) {
        LambdaQueryWrapper<ZWjglFl> lqw = buildQueryWrapper(bo);
        List<ZWjglFlVo> zWjglFlVos = baseMapper.selectVoList(lqw);
        // 如果有图片的话，则获取图片的base64字符串
//        for (ZWjglFlVo zWjglFlVo : zWjglFlVos) {
//            String type = zWjglFlVo.getFiletype();
//            if (StringUtils.isNotEmpty(type) && (".png".equals(type) || ".jpg".equals(type) || ".jpeg".equals(type))) {
//                // 2.获取附件路径
//                String path = uploadPath + zWjglFlVo.getFilepath();
//                Path filePath = Paths.get(path);
//                // 3.获取文件
//                byte[] imageBytes = new byte[0];
//                try {
//                    imageBytes = Files.readAllBytes(filePath);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//                String imgType = "";
//                if (".png".equals(type)) {
//                    imgType = "image/png";
//                }else if (".jpg".equals(type)) {
//                    imgType = "image/jpg";
//                }else if (".jpeg'".equals(type)) {
//                    imgType = "image/jpeg";
//                }
//                // 进行 Base64 编码
//                String imageBase64 = "data:"+imgType+";base64," + Base64.getEncoder().encodeToString(imageBytes);
//                zWjglFlVo.setFileBase64(imageBase64);
//            }
//        }
        return queryTreeList(zWjglFlVos, bo.getPid());
    }

    @Override
    public List<ZWjglFlVo> queryListExcel(ZWjglFlBo bo) {
        LambdaQueryWrapper<ZWjglFl> lqw = buildQueryWrapper(bo);
        List<ZWjglFlVo> zWjglFlVos = baseMapper.selectVoList(lqw);
        return zWjglFlVos;
    }

    /**
     * 转树型
     * @param
     * @return
     */
    public List<Tree<String>> queryTreeList(List<ZWjglFlVo> list, String pid) {
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都有默认值的
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setParentIdKey("pid");
        // 最大递归深度
        treeNodeConfig.setDeep(3);
        //转换器 (含义:找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
        List<Tree<String>> treeNodes = TreeUtil.build(list, StringUtils.isNotEmpty(pid) ? pid : "0", treeNodeConfig, (object, tree) -> {
            tree.putExtra("id", object.getId());
            tree.putExtra("pid", object.getPid());
            tree.putExtra("filename", object.getFilename());
            tree.putExtra("filecode", object.getFilecode());
            tree.putExtra("filetype", object.getFiletype());
            tree.putExtra("icon", object.getIcon());
            tree.putExtra("iconcolor", object.getIconcolor());
            tree.putExtra("fileauth", object.getFileauth());
            tree.putExtra("filepassword", object.getFilepassword());
            tree.putExtra("collect", object.getCollect());
            tree.putExtra("filepath", object.getFilepath());
            tree.putExtra("px", object.getPx());
            tree.putExtra("readonly", object.getReadonly());
            tree.putExtra("category", object.getCategory());
            tree.putExtra("createId", object.getCreateId());
            tree.putExtra("createTime", object.getCreateTime());
            tree.putExtra("createBy", object.getCreateBy());
            tree.putExtra("updateTime", object.getUpdateTime());
            tree.putExtra("updateBy", object.getUpdateBy());
//            tree.putExtra("fileBase64", object.getFileBase64());
        });
        return treeNodes;
    }

    private LambdaQueryWrapper<ZWjglFl> buildQueryWrapper(ZWjglFlBo bo) {
        LambdaQueryWrapper<ZWjglFl> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getPid()), ZWjglFl::getPid, bo.getPid());
        lqw.like(StringUtils.isNotBlank(bo.getFilename()), ZWjglFl::getFilename, bo.getFilename());
        lqw.eq(StringUtils.isNotBlank(bo.getFilecode()), ZWjglFl::getFilecode, bo.getFilecode());
        lqw.eq(StringUtils.isNotBlank(bo.getFiletype()), ZWjglFl::getFiletype, bo.getFiletype());
        lqw.eq(StringUtils.isNotBlank(bo.getFileauth()), ZWjglFl::getFileauth, bo.getFileauth());
        lqw.eq(StringUtils.isNotBlank(bo.getFilepassword()), ZWjglFl::getFilepassword, bo.getFilepassword());
        lqw.eq(StringUtils.isNotBlank(bo.getCreateId()), ZWjglFl::getCreateId, bo.getCreateId());
        lqw.eq(bo.getCollect() != null, ZWjglFl::getCollect, bo.getCollect());
        // 种类
        if (StringUtils.isNotEmpty(bo.getCategory())) {
            List<String> strings = Arrays.asList(bo.getCategory().split(","));
            lqw.in(ZWjglFl::getCategory, strings);
        }
        // 设置排序类型

        if (StringUtils.isNotBlank(bo.getOrderByCode())) {
            getOrder(lqw, bo.getOrderByCode());
        }else {
            lqw.orderByAsc(ZWjglFl::getCategory);
            lqw.orderByAsc(ZWjglFl::getPx);
            lqw.orderByAsc(ZWjglFl::getCreateTime);
        }

        return lqw;
    }

    private LambdaQueryWrapper<ZWjglFl> getOrder(LambdaQueryWrapper<ZWjglFl> lqw, String orderByCode) {
        String[] split = orderByCode.split(",");
        String file = split[0];
        String order = split[1];
        switch (file) {
            case "cjsj":
                lqw = "dz".equals(order)?lqw.orderByAsc(ZWjglFl::getCreateTime) : lqw.orderByDesc(ZWjglFl::getCreateTime);
                break;
            case "xgsj":
                lqw = "dz".equals(order)?lqw.orderByAsc(ZWjglFl::getUpdateTime) : lqw.orderByDesc(ZWjglFl::getUpdateTime);
                break;
            case "wjpx":
                lqw = "dz".equals(order)?lqw.orderByAsc(ZWjglFl::getPx) : lqw.orderByDesc(ZWjglFl::getPx);
                break;
        }
        return lqw;
    }

    /**
     * 新增文件管理分类
     */
    @Override
    public Boolean insertByBo(ZWjglFlBo bo) {
        ZWjglFl add = BeanUtil.toBean(bo, ZWjglFl.class);
        LoginUser loginUser = LoginHelper.getLoginUser();
        String id = IdUtil.simpleUUID();
        add.setId(id);
        add.setCreateId(loginUser.getUserId()+"");
        add.setUpdateBy(loginUser.getUsername());
        add.setCreateBy(loginUser.getUsername());
        add.setUpdateTime(new Date());
        add.setCreateTime(new Date());
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改文件管理分类
     */
    @Override
    public Boolean updateByBo(ZWjglFlBo bo) {
        ZWjglFl update = BeanUtil.toBean(bo, ZWjglFl.class);
        LoginUser loginUser = LoginHelper.getLoginUser();
        update.setUpdateTime(new Date());
        update.setUpdateBy(loginUser.getUsername());
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZWjglFl entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除文件管理分类
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 保存文件
     * @param bo
     * @return
     */
    @Override
    public boolean saveFile(ZWjglFlBo bo) {
        // 判断当前文件类型
        boolean success = false;
        String filetype = bo.getFiletype();
        if (filetype.equals(".txt")) {
            success = saveTxt(bo);
        }
        return success;
    }

    public boolean saveTxt(ZWjglFlBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        // 1.先创建文件夹
        LocalDate currentDate = LocalDate.now();
        // 分别获取年、月、日
        int year = currentDate.getYear();
        int monthValue = currentDate.getMonthValue();
        int dayOfMonth = currentDate.getDayOfMonth();
        // 生成Excel路径
        String suffixPath = "/" + year + "/" + monthValue + "/" + dayOfMonth + "/";
        // 判断当前文件路径的文件夹是否存在，不存在则创建
        if (!Files.exists(Paths.get(uploadPath + suffixPath))) {
            // 路径不存在，尝试创建
            try {
                Files.createDirectories(Paths.get(uploadPath + suffixPath));
            } catch (Exception e) {
                System.err.println("创建目录时出错: " + e.getMessage());
            }
        }
        // 2.将文件保存到指定目录
        try {
            String path = uploadPath + suffixPath + bo.getFilename() + bo.getFiletype();
            // 写入内容
            Files.write(Paths.get(path), bo.getContent().getBytes());
            // 3.将文件路径存入
            bo.setFilepath(suffixPath + bo.getFilename() + bo.getFiletype());
            bo.setUpdateTime(new Date());
            bo.setUpdateBy(loginUser.getUsername());
        } catch (IOException e) {
            // 处理异常
            System.err.println("文件创建或写入时发生错误: " + e.getMessage());
        }
        // 修改文件
        return updateByBo(bo);
    }

    @Override
    public String getFileContent(String id) {
        String content = "";
        ZWjglFlVo wjglFl = queryById(id);
        if (wjglFl != null && StringUtils.isNotBlank(wjglFl.getFilepath())) {
            content = readFileContent(uploadPath + wjglFl.getFilepath());
        }
        return content;
    }

    public String readFileContent(String filePath) {
        StringBuilder contentBuilder = new StringBuilder();
        try (FileInputStream fis = new FileInputStream(filePath);
             InputStreamReader isr = new InputStreamReader(fis)) {
            int ch;
            while ((ch = isr.read()) != -1) {
                contentBuilder.append((char) ch);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return contentBuilder.toString();
    }

    @Override
    public boolean verifyFileName(String fileName, String filetype) {
        List<ZWjglFl> list = baseMapper.verifyFileName(fileName, filetype);
        return list.size() > 0;
    }

    /**
     * 获取最大排序
     * @param pid
     * @return
     */
    @Override
    public Integer queryMaxPx(String pid) {
        return baseMapper.queryMaxPx(pid);
    }

    /**
     * 批量下载
     * @param ids
     * @return
     */
    @Override
    public List<ZWjglFlVo> queryListByIds(String ids) {
        List<String> list = Arrays.stream(ids.split(",")).collect(Collectors.toList());
        List<ZWjglFlVo> zWjglFlVoList = baseMapper.selectVoBatchIds(list);
        return zWjglFlVoList;
    }

}
